﻿using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using PDFSignature.Helper;
using PDFSignature.Models;
using PDFSignature.Models.Entitys;
using Spire.Pdf;
using Spire.Pdf.General.Find;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Threading.Tasks;
using Newtonsoft.Json;
using System.IO;
using System.Net;
using Microsoft.Extensions.Caching.Memory;

namespace PDFSignature.Controllers
{
    public class HomeController : Controller
    {
        private readonly ILogger<HomeController> _logger;
        private readonly Dictionary<string, string> _ContractPartysMap = new Dictionary<string, string>()
        {
            {"0", "甲方" },
            {"1", "乙方" },
            {"2", "丙方" },
            {"3", "丁方" },
            {"4", "戊方" },
            {"5", "己方" },
            {"6", "庚方" },
        };
        private readonly  IWebHostEnvironment _environment;
        private readonly IMemoryCache _memoryCache;


        public HomeController(ILogger<HomeController> logger, IWebHostEnvironment environment, IMemoryCache memoryCache)
        {
            _logger = logger;
            _environment = environment;
            _memoryCache = memoryCache;
        }

        public IActionResult Index()
        {
            return View();
        }





        [Route("GetSignatureDataBySessionId")]
        [HttpGet]
        public IActionResult GetSignatureDataBySessionId([FromQuery] string sessionId)
        {
            try
            {
                SignatureView data = _memoryCache.Get<SignatureView>(sessionId);
                if (data == null)
                {
                    return Json(new ApiResponse("SessionId无效"));
                }


                try
                {
                    string localDire = Path.Combine("contract", DateTime.Now.ToString("yyyyMMdd"));
                    string folderpath = Path.Combine(_environment.WebRootPath, localDire);
                    if (!Directory.Exists(folderpath))
                    {
                        Directory.CreateDirectory(folderpath);
                    }
                    string fileName = Guid.NewGuid().ToString("N") + data.PdfUrl[data.PdfUrl.LastIndexOf(".")..];
                    var path = Path.Combine(folderpath, fileName);
                    WebClient mywebclient = new WebClient();

                    mywebclient.DownloadFile(data.PdfUrl, path);
                    data.PdfPath = Path.Combine(localDire, fileName);
                }
                catch (Exception ex)
                {
                    return Json(new ApiResponse("读取远程pdf文件失败:" + ex.Message));
                }


                return Json(new ApiResponse<SignatureView>()
                {
                    Succeed = true,
                    Data = data
                });
            }
            catch (Exception ex)
            {
                return Json(new ApiResponse(ex.Message));
            }
        }


        /// <summary>
        /// 签章数据存入缓存 供后续打开页面读取
        /// </summary>
        /// <param name="view"></param>
        /// <returns></returns>
        [Route("GetSessionGuid")]
        [HttpPost]
        public IActionResult GetSessionGuid([FromBody] SignatureView view)
        {
            try
            {
                string guid = Guid.NewGuid().ToString();
                _memoryCache.Set(guid, view, TimeSpan.FromSeconds(3600));
                return Json(new ApiResponse<string>()
                {
                    Succeed = true,
                    Data = guid
                });
            }
            catch(Exception ex)
            {
                return Json(new ApiResponse(ex.Message));
            }
         
        }




        [Route("GetSignatureData")]
        [HttpPost]
        public async Task<IActionResult>  GetSignatureData([FromBody]GetSignatureDataInput input)
        {
            #region 校验一下
            if (input == null)
            {
                return Json(new ApiResponse("输入为空"));
            }
            if (string.IsNullOrEmpty(input.ContractId))
            {
                return Json(new ApiResponse("合同编号为空"));
            }
            if (string.IsNullOrEmpty(input.ContractName))
            {
                return Json(new ApiResponse("合同名称为空"));
            }
            if (string.IsNullOrEmpty(input.PdfUrl))
            {
                return Json(new ApiResponse("缺少pdf路径"));
            }
            if (input.ContractPartysInfos==null || input.ContractPartysInfos.Count<1)
            {
                return Json(new ApiResponse("请提供签章方信息"));
            }
            if(input.ContractPartysInfos.Select(it=>it.ContractPartys).Distinct().Count() != input.ContractPartysInfos.Count)
            {
                return Json(new ApiResponse("存在多个相同的签约方"));
            }
            if (input.ContractPartysInfos.Select(it => it.Sequence).Distinct().Count() != input.ContractPartysInfos.Count)
            {
                return Json(new ApiResponse("存在多个相同的签章顺序"));
            }
            #endregion

            var db = DbHelper.GetInstance();

            if (!input.NotReadLibrary)
            {
                var cach = await db.Queryable<PdfAnalysis>().Where(it => it.FileName == input.PdfUrl).FirstAsync();
                if (cach != null)
                {
                    try
                    {
                        ApiResponse<SignatureView> resp = new ApiResponse<SignatureView>()
                        {
                            Succeed = true,
                            Data = JsonConvert.DeserializeObject<SignatureView>(cach.SerializeJson)

                        };
                        return Json(resp);
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("反序列化失败: " + ex.Message);
                    }
                }
            }
           


            PdfAnalysis pdfAnalysis = new PdfAnalysis()
            {
                CreateDatetime = DateTime.Now,
                FileName = input.PdfUrl,
                Guid = Guid.NewGuid().ToString(),
                LocalPath = "",
                SerializeJson = ""
            };

            try
            {
                string localDire = Path.Combine("contract", DateTime.Now.ToString("yyyyMMdd"));
                string folderpath = Path.Combine(_environment.WebRootPath, localDire);
                if (!Directory.Exists(folderpath))
                {
                    Directory.CreateDirectory(folderpath);
                }
                string fileName = Guid.NewGuid().ToString("N") + input.PdfUrl[input.PdfUrl.LastIndexOf(".")..];
                var path = Path.Combine(folderpath, fileName);
                WebClient mywebclient = new WebClient();

                mywebclient.DownloadFile(input.PdfUrl, path);
                pdfAnalysis.LocalPath = Path.Combine(localDire, fileName);
            }
            catch(Exception ex)
            {
                return Json(new ApiResponse("读取远程pdf文件失败:" + ex.Message));
            }

            SignatureView data = new SignatureView()
            {
                ContractName = input.ContractName,
                ContractId = input.ContractId,
                ContractPartysInfos = input.ContractPartysInfos,
                PdfUrl = pdfAnalysis.FileName,
                Signatures = new List<Signature>(),
                PageInfos = new List<PageInfo>()
            };

            string localPath = Path.Combine(_environment.WebRootPath, pdfAnalysis.LocalPath);
            PdfDocument doc = new PdfDocument();
            doc.LoadFromFile(localPath);
            int pageIndex = 0;
            foreach (PdfPageBase page in doc.Pages)
            {
                pageIndex++;
                data.PageInfos.Add(new PageInfo()
                {
                    Height = page.Size.Height,
                    PageIndex = pageIndex,
                    Width = page.Size.Width
                });

                foreach (var c in data.ContractPartysInfos)
                {
                    PdfTextFind[] results = page.FindText($"{_ContractPartysMap[c.ContractPartys]}盖章", TextFindParameter.WholeWord).Finds;
                    foreach (PdfTextFind text in results)
                    {
                        PointF p = text.Position;
                        var sign = new Signature()
                        {
                            ContractPartys = c.ContractPartys,
                            KeyWord = $"{_ContractPartysMap[c.ContractPartys]}盖章",
                            PageIndex = pageIndex,
                            PosX = string.Format("{0:F3}", p.X + 10).ObjToFloat(),
                            PosY = string.Format("{0:F3}", p.Y-60).ObjToFloat(), 
                            SignMode = TakeAimMode.Coordinate,
                            SealType = SealTypeEnum.CorporateSeal
                        };
                        data.Signatures.Add(sign);
                    }


                    PdfTextFind[] results2 = page.FindText($"{_ContractPartysMap[c.ContractPartys]}签字", TextFindParameter.WholeWord).Finds;
                    foreach (PdfTextFind text in results2)
                    {
                        PointF p = text.Position;
                        var sign = new Signature()
                        {
                            ContractPartys = c.ContractPartys,
                            KeyWord = $"{_ContractPartysMap[c.ContractPartys]}签字",
                            PageIndex = pageIndex,
                            PosX = string.Format("{0:F3}", p.X + 10).ObjToFloat(),
                            PosY = string.Format("{0:F3}", p.Y - 60).ObjToFloat(),
                            SignMode = TakeAimMode.Coordinate,
                            SealType = SealTypeEnum.PersonalSeal
                        };
                        data.Signatures.Add(sign);
                    }


                    PdfTextFind[] results3 = page.FindText($"{_ContractPartysMap[c.ContractPartys]}盖章人签字", TextFindParameter.WholeWord).Finds;
                    foreach (PdfTextFind text in results3)
                    {
                        PointF p = text.Position;
                        var sign = new Signature()
                        {
                            ContractPartys = c.ContractPartys,
                            KeyWord = $"{_ContractPartysMap[c.ContractPartys]}盖章人签",
                            PageIndex = pageIndex,
                            PosX = string.Format("{0:F3}", p.X + 10).ObjToFloat(),
                            PosY = string.Format("{0:F3}", p.Y - 60).ObjToFloat(),
                            SignMode = TakeAimMode.Coordinate,
                            SealType = SealTypeEnum.ProxySeal
                        };
                        data.Signatures.Add(sign);
                    }
                }
            }

            pdfAnalysis.SerializeJson = JsonConvert.SerializeObject(data);
            if (input.NotReadLibrary)
            {
                await db.Deleteable<PdfAnalysis>().Where(it => it.FileName == pdfAnalysis.FileName).ExecuteCommandAsync();
            }
            await db.Insertable(pdfAnalysis).ExecuteCommandAsync();

            return Json( new ApiResponse<SignatureView>()
            {
                Succeed = true,
                Data = data
            });
        }

    }
}
